import Vue from 'vue'
import eventBus from '@/js/eventbus'
const taskWebsocket = new class taskSocket {
  //是否连接
  // static isConnection = false;
  constructor() {
    // //是否连接
    // // this.isConnection = false;
    // //连接id
    // this.connectionId = '';
    // //定时器的id
    // this.intervalId = 0;
    this.vue = new Vue();
    // //websocket地址
    // this.wsUrl = '';
  }

  //连接 websocket信息
  async connection(wsUrl, userId) {
    //验证 是否已经注入了连接
    if (!taskSocketState.isConnection) {
      await this.vue.$connect(`${wsUrl}?ConnectionId=${userId}`)
      taskSocketState.connectionId = userId;
      taskSocketState.wsUrl = wsUrl;
      //监听事件处理
      this.vue.$socket.onmessage = this.onMessage;
      this.vue.$socket.onopen = this.onOpen;
      this.vue.$socket.onerror = this.onError;
      this.vue.$socket.onclose = this.onClose;
      //更改连接状态
      taskSocketState.isConnection = true;
    }
  }
  //断开连接
  disconnect() {
    this.vue.$disconnect()
    taskSocketState.isConnection = false;
    //关闭定时器
    clearInterval(taskSocketState.intervalId)
  }

  //#region 事件监听
  onOpen(e) {
    //  链接ws服务器，e.target.readyState = 0/1/2/3
    //0 CONNECTING ,1 OPEN, 2 CLOSING, 3 CLOSED
    //开启定时服务定期给服务端发送消息
    taskSocketState.intervalId = setInterval(() => {
      this.send(JSON.stringify({
        action: 'HeartbeatCheck',
      }));
    }, 30 * 1000)
    console.log(new Date(), "WebSocket连接成功", e);
  }

  onError(e) {
    //错误
    console.log(new Date(), "WebSocket连接发生错误");

    taskSocketState.isConnection = false;
    //关闭定时器
    clearInterval(taskSocketState.intervalId)
  }
  //接收消息
  onMessage(e) {
    //数据接收
    var reciveMsg = JSON.parse(e.data);
    //发布消息给订阅者
    eventBus.getInstance().publish(reciveMsg.action, reciveMsg ? reciveMsg.message : {});
  }
  onClose(e) {
    //关闭链接时触发
    //  状态码表 https://developer.mozilla.org/zh-CN/docs/Web/API/CloseEvent
    console.log(new Date(), e);
    taskSocketState.isConnection = false;
    //关闭定时器
    clearInterval(taskSocketState.intervalId)
  }

  //#endregion

  //发送消息
  //msg 消息的json对象信息
  //action 远程调用的方法名
  async sendMessage(action, msg) {
    //验证连接状态
    if (taskSocketState.isConnection) {
      //数据发送
      await this.vue.$socket.send(this.buildSendMessage(action, msg));
    } else {
      await this.connection(taskSocketState.wsUrl, taskSocketState.connectionId);
      //由于此时可能连接没有连接成功 所以延迟1s发送消息
      //如果1s没有发送成功就直接发送失败
      setTimeout(async () => {
        //数据发送
        await this.vue.$socket.send(this.buildSendMessage(action, msg));
      }, 1000*1)
    }
  }
  //构建发送的消息
  buildSendMessage(action, sendMessage) {
    return JSON.stringify({
      action: action,
      message: sendMessage
    });
  }
}
//socket的状态信息 存储
class taskSocketState {
  //是否连接
  static isConnection = false;
  //连接id
  static connectionId = '';
  //定时器的id
  static intervalId = 0;
  //websocket地址
  static wsUrl = '';
}

export default taskWebsocket
